// Copyright (C) 2022 Huawei Device Co., Ltd.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package utils

const (
	RowTypeCpu                = "Cpu"
	RowTypeCpuState           = "Cpu State"
	RowTypeCpuFreq            = "Cpu Frequency"
	RowTypeCpuFreqLimit       = "Cpu FreqLimit"
	RowTypeFps                = "Fps"
	RowTypeNativeMemory       = "Native Memory"
	RowTypeHiperf             = "Hiperf"
	RowTypeDeliverInputEvent  = "DeliverInputEvent"
	RowTypeProcess            = "Process"
	RowTypeFileSystem         = "File System"
	RowTypeMonitor            = "Ability Monitor"
	RowTypeSdk                = "Sdk"
	RowTypeEnergy             = "Energy"
	RowTypeSmaps              = "VM Tracker"
	RowTypeClock              = "Clock"
	RowTypeIrq                = "Irq"
	RowTypeJank               = "Janks"
	RowTypeBIO                = "Bio"
	RowTypePageFault          = "Page Fault"
	RowTypeSchedulingAnalysis = "Scheduling Analysis"
	RowTypeMem                = "Memory"
	RowTypeVirtualMemory      = "Virtual Memory"
	RowTypeJsMemory           = "JsMemory"
	RowTypeHang               = "Hang"
)

const rowType string = "row"
const tabType string = "tab"

var (
	BusinessRowTypeCpu = map[string]string{
		"Cpu":                         rowType,
		"Current Selection(cpu-data)": tabType,
		"CPU by thread":               tabType,
		"CPU by process":              tabType,
		"CPU Usage":                   tabType,
		"States List":                 tabType,
		"Switches List":               tabType,
		"Thread States(cpu-data)":     tabType,
		"Thread Switches":             tabType,
	}
	BusinessRowTypeCpuFreq = map[string]string{
		"Cpu Frequency": rowType + tabType,
		"Frequency":     tabType,
	}

	BusinessRowTypeCpuState = map[string]string{
		"Cpu State": rowType + tabType,
	}

	BusinessRowTypeCpuFreqLimit = map[string]string{
		"Cpu Freq Limit":       rowType,
		"Cpu Frequency Limits": tabType,
	}

	BusinessRowTypeClock = map[string]string{
		"Clocks":                   rowType,
		"clock":                    rowType,
		"Current Selection(clock)": tabType,
		"Clock Counters":           tabType,
	}

	BusinessRowTypeIrq = map[string]string{
		"Irqs":                   rowType,
		"irq":                    rowType,
		"Irq Counters":           tabType,
		"Current Selection(irq)": tabType,
	}

	BusinessRowTypeDeliverInputEvent = map[string]string{
		"DeliverInputEvent":                    rowType,
		"DeliverInputEvent Func":               rowType,
		"Slices(deliverInputEvent)":            tabType,
		"Current Selection(deliverInputEvent)": tabType,
	}

	BusinessRowTypeFps = map[string]string{
		"FPS": rowType + tabType,
	}

	BusinessRowTypeNativeMemory = map[string]string{
		"Native Memory":           rowType + tabType,
		"All Heap & Anonymous VM": rowType,
		"All Heap":                rowType,
		"All Anonymous VM":        rowType,
		"Analysis(heap)":          tabType,
		"Statistics":              tabType,
		"Call Info":               tabType,
		"Snapshot List":           tabType,
	}

	BusinessRowTypeHiperf = map[string]string{
		"HiPerf (All)":         rowType,
		"HiPerf":               rowType,
		"HiPerf Cpu":           rowType,
		"HiPerf Process":       rowType,
		"HiPerf Thread":        rowType,
		"HiPerf Report":        rowType,
		"HiPerf Event":         rowType,
		"Sample List":          tabType,
		"Perf Profile":         tabType,
		"Analysis(hiperf-cpu)": tabType,
	}

	BusinessRowTypeMonitor = map[string]string{
		"Ability Monitor":        rowType,
		"Cpu Ability":            rowType,
		"Memory Ability":         rowType,
		"DiskIO Ability":         rowType,
		"Network Ability":        rowType,
		"Live Processes":         tabType,
		"Processes History":      tabType,
		"System CPU Summary":     tabType,
		"System Memory Summary":  tabType,
		"System Disk Summary":    tabType,
		"System Network Summary": tabType,
	}

	BusinessRowTypeSdk = map[string]string{
		"Sdk":         rowType,
		"SDK Counter": tabType,
		"Sdk Slice":   tabType,
	}

	BusinessRowTypeEnergy = map[string]string{
		"Energy":                    rowType,
		"Anomaly Event":             rowType,
		"System Event":              rowType,
		"Power":                     rowType,
		"Power Event":               rowType,
		"Brightness Nit":            rowType,
		"Signal Level":              rowType,
		"Wifi Event Received":       rowType,
		"Audio Stream Change":       rowType,
		"Audio Volume Change":       rowType,
		"Wifi State":                rowType,
		"Bluetooth Br Switch State": rowType,
		"Location Switch State":     rowType,
		"Sensor State":              rowType,
		"Anomaly details":           tabType,
		"System Details":            tabType,
		"Power Battery":             tabType,
		"Power Details":             tabType,
	}

	BusinessRowTypeSmaps = map[string]string{
		"VM Tracker":             rowType,
		"Dirty Size":             rowType,
		"Swapped Size":           rowType,
		"Resident Size":          rowType,
		"VM Tracker Statistics":  tabType,
		"VM Tracker Record List": tabType,
	}

	BusinessRowTypeJank = map[string]string{
		"FrameTimeLine":            rowType,
		"render_service":           rowType,
		"app":                      rowType,
		"Frames":                   tabType,
		"Current Selection(janks)": tabType,
	}

	BusinessRowTypeFileSystem = map[string]string{
		"FileSystem Logical Read":    rowType,
		"FileSystem Logical Write":   rowType,
		"Filesystem statistics":      tabType,
		"Filesystem Calltree":        tabType,
		"Filesystem Events":          tabType,
		"File Descriptor History":    tabType,
		"File Descriptor Time Slice": tabType,
		"Analysis(file-system-cell)": tabType,
	}

	BusinessRowTypeBIO = map[string]string{
		"Disk I/O Latency":          rowType,
		"Bio Process":               rowType,
		"Disk I/O Tier Statistics":  tabType,
		"Disk I/O Latency Calltree": tabType,
		"Trace Completion Times":    tabType,
		"Analysis(disk-io)":         tabType,
	}

	BusinessRowTypePageFault = map[string]string{
		"Page Fault Trace":              rowType,
		"Page Fault Statistics":         tabType,
		"Page Fault CallTree":           tabType,
		"Page Fault Events":             tabType,
		"Analysis(virtual-memory-cell)": tabType,
	}

	BusinessRowTypeProcess = map[string]string{
		"Process":                   rowType,
		"Thread":                    rowType,
		"Func":                      rowType,
		"Slices(process)":           tabType,
		"Slices(func)":              tabType,
		"Slices(thread)":            tabType,
		"Current Selection(func)":   tabType,
		"Thread States(func)":       tabType,
		"Thread States(thread)":     tabType,
		"Thread Usage":              tabType,
		"Current Selection(thread)": tabType,
		"Counters(thread)":          tabType,
	}

	BusinessRowTypeMem = map[string]string{
		"Memory":        rowType,
		"Slices(mem)":   tabType,
		"Counters(mem)": tabType,
	}

	BusinessRowTypeVirtualMemoryGroup = map[string]string{
		"Virtual Memory":                rowType,
		"Counters(virtual-memory-cell)": tabType,
	}

	BusinessRowTypeSchedulingAnalysis = map[string]string{
		"Scheduling Analysis":        rowType,
		"CPU Data":                   tabType,
		"Thread Analysis":            tabType,
		"CPU Idle":                   tabType,
		"CPU Frequency":              tabType,
		"CPU Irq":                    tabType,
		"Analysis Page":              tabType,
		"Top20 Thread Cpu Usage":     tabType,
		"Top20 Frequency Thread":     tabType,
		"Top20 Thread Run Time":      tabType,
		"Top20 Process Thread Count": tabType,
		"Top20 Process Switch Count": tabType,
		"Analysis Upload":            tabType,
		"Analysis CPU Idle":          tabType,
		"Analysis CPU Frequency":     tabType,
		"Analysis CPU Irq":           tabType,
	}

	BusinessRowTypeJSHeap = map[string]string{
		"Heapsnapshot": rowType,
		"Heaptimeline": rowType,
		"Summary":      tabType,
		"Comparison":   tabType,
	}

	BusinessRowTypeHang = map[string]string{
		"Hang": rowType + tabType,
	}
)

func GetBusinessType(event string) string {
	businessType := ""
	if _, ok := BusinessRowTypeCpu[event]; ok {
		businessType = RowTypeCpu
	} else if _, ok := BusinessRowTypeCpuState[event]; ok {
		businessType = RowTypeCpuState
	} else if _, ok := BusinessRowTypeCpuFreq[event]; ok {
		businessType = RowTypeCpuFreq
	} else if _, ok := BusinessRowTypeCpuFreqLimit[event]; ok {
		businessType = RowTypeCpuFreqLimit
	} else if _, ok := BusinessRowTypeFps[event]; ok {
		businessType = RowTypeFps
	} else if _, ok := BusinessRowTypeNativeMemory[event]; ok {
		businessType = RowTypeNativeMemory
	} else if _, ok := BusinessRowTypeHiperf[event]; ok {
		businessType = RowTypeHiperf
	} else if _, ok := BusinessRowTypeDeliverInputEvent[event]; ok {
		businessType = RowTypeDeliverInputEvent
	} else if _, ok := BusinessRowTypeProcess[event]; ok {
		businessType = RowTypeProcess
	} else if _, ok := BusinessRowTypeFileSystem[event]; ok {
		businessType = RowTypeFileSystem
	} else if _, ok := BusinessRowTypeMonitor[event]; ok {
		businessType = RowTypeMonitor
	} else if _, ok := BusinessRowTypeSdk[event]; ok {
		businessType = RowTypeSdk
	} else if _, ok := BusinessRowTypeEnergy[event]; ok {
		businessType = RowTypeEnergy
	} else if _, ok := BusinessRowTypeSmaps[event]; ok {
		businessType = RowTypeSmaps
	} else if _, ok := BusinessRowTypeClock[event]; ok {
		businessType = RowTypeClock
	} else if _, ok := BusinessRowTypeIrq[event]; ok {
		businessType = RowTypeIrq
	} else if _, ok := BusinessRowTypeJank[event]; ok {
		businessType = RowTypeJank
	} else if _, ok := BusinessRowTypeBIO[event]; ok {
		businessType = RowTypeBIO
	} else if _, ok := BusinessRowTypePageFault[event]; ok {
		businessType = RowTypePageFault
	} else if _, ok := BusinessRowTypeMem[event]; ok {
		businessType = RowTypeMem
	} else if _, ok := BusinessRowTypeVirtualMemoryGroup[event]; ok {
		businessType = RowTypeVirtualMemory
	} else if _, ok := BusinessRowTypeSchedulingAnalysis[event]; ok {
		businessType = RowTypeSchedulingAnalysis
	} else if _, ok := BusinessRowTypeJSHeap[event]; ok {
		businessType = RowTypeJsMemory
	} else if _, ok := BusinessRowTypeHang[event]; ok {
		businessType = RowTypeHang
	}
	return businessType
}

const PAGE_VISIT = `-- 7日访问量
SELECT
    'sevenDayAccess' as key, count(1) as num, 5 as index
FROM
    sp_user_access
WHERE
    access_time BETWEEN (SELECT CURRENT_DATE - INTERVAL '6 day') AND (SELECT CURRENT_DATE + INTERVAL '1 day')
-- 30日访问量
UNION
SELECT
    'mouthDayAccess' as key, count(1) as num, 6 as index
FROM
    sp_user_access
WHERE
    access_time BETWEEN (SELECT CURRENT_DATE - INTERVAL '29 day') AND (SELECT CURRENT_DATE + INTERVAL '1 day')
--累计访问量
UNION
SELECT
    'allAccess' as key, count(1) as num, 7 as index
FROM
    sp_user_access
    order by index`

const PAGE_USER = `-- 新增用户
SELECT
    'addUser' as key, count(1) as num, 1 as index
FROM
    sp_user
WHERE
    create_time BETWEEN (SELECT now( ) - INTERVAL '1 day') AND (SELECT now( ))
UNION
-- 近7日活跃用户数
SELECT acc.key,count(1), 2 as index 
FROM 
(SELECT ud.key,ud.user_id
FROM
(SELECT
    'sevenDayUser' as key,to_char(access_time, 'YYYY-MM-DD') AS d,user_id
FROM
    sp_user_access
WHERE
    access_time BETWEEN (SELECT CURRENT_DATE - INTERVAL '6 day') AND (SELECT CURRENT_DATE + INTERVAL '1 day')
GROUP BY user_id,d having count(user_id)>10) as ud
GROUP BY ud.key,ud.user_id) as acc
GROUP BY acc.key
-- 近30日活跃用户数
UNION
SELECT acc.key,count(1), 3 as index 
FROM 
(SELECT ud.key,ud.user_id
FROM
(SELECT
    'mouthDayUser' as key,to_char(access_time, 'YYYY-MM-DD') AS d,user_id
FROM
    sp_user_access
WHERE
    access_time BETWEEN (SELECT CURRENT_DATE - INTERVAL '29 day') AND (SELECT CURRENT_DATE + INTERVAL '1 day')
GROUP BY user_id,d having count(user_id)>10) as ud
GROUP BY ud.key,ud.user_id) as acc
GROUP BY acc.key
-- 累计用户数
UNION
SELECT
    'allUser' as key, count(1) as num, 4 as index
FROM
    sp_user order by index
`

const HOME_PAGE_CHART_SQL = `SELECT 'addUser' as key,to_char(create_time, '%s') as d, 
count(1) AS num,0 as user_id from sp_user p WHERE p.create_time >= $1 AND p.create_time <= $2 group by d
UNION
SELECT au.key,au.d,count(1) as num,0 AS user_id
FROM
(SELECT
    'activeUser' as key,to_char(access_time, '%s') as d,count(1) as num,user_id
FROM
    sp_user_access
WHERE
    access_time >= $1 AND access_time <= $2
GROUP BY d,user_id HAVING count(user_id) > 10) as au
GROUP BY au.d,au.key
UNION
SELECT
  'access' AS KEY,to_char(access_time, '%s') AS d,COUNT ( 1 ) AS num,0 as user_id
FROM
  sp_user_access 
WHERE
access_time >= $1 AND access_time <= $2 
GROUP BY d 
UNION
SELECT 'beforeTotalUser' as key,'' as d, count(1) AS num,0 as user_id from sp_user p WHERE p.create_time < $1
UNION
SELECT 'totalUser' as key,to_char(create_time, '%s') as d, count(1) AS num,0 as user_id
from sp_user p WHERE p.create_time >= $1 AND p.create_time <= $2 GROUP BY d
ORDER BY key,d`

const PAGE_USE_SQL = `SELECT
  to_char( P.ts, '%s' ) AS d,
  COUNT ( 1 ) AS COUNT 
FROM
  sp_records P 
WHERE
  ts BETWEEN $1 AND $2 
  AND P.ACTION =$3 
GROUP BY d
ORDER BY d`

const GET_USE_PLUGIN_SQL = `SELECT
  expand_content AS pluginName,
  COUNT ( * ) 
FROM
  sp_records_expand sre 
WHERE
  to_timestamp(expand_id/1000000000) BETWEEN $1 AND $2
GROUP BY
  expand_content`

const GET_USE_SQL = `SELECT
  to_char( P.ts, '%s' ) AS d,
  COUNT ( 1 ) AS COUNT 
FROM
  sp_records P 
WHERE
    ts BETWEEN $1 AND $2
  AND p.event = $3
    AND P.action = $4
GROUP BY d`

const ROW_TAB_COUNT_SQL = `SELECT
  business_type,
  COUNT ( 1 ) AS num 
FROM
  sp_records 
WHERE
  ts BETWEEN $1 
  AND $2 
  AND business_type <> '' 
GROUP BY
  business_type`

const ROW_TAB_SUB_COUNT_SQL string = `SELECT
  concat_ws(':',event,action) as event,
  business_type,
  COUNT ( 1 ) AS num 
FROM
  sp_records 
WHERE
  ts BETWEEN $1 
  AND $2 
  AND business_type <> '' 
GROUP BY
business_type,event,action
ORDER BY business_type,num desc`

const IMPORT_SQL = `
SELECT
  to_char( P.ts, '%s' ) AS d,
  COUNT ( 1 ) AS COUNT 
FROM
  sp_records P 
WHERE
     ts BETWEEN $1 AND $2 
     AND
     P.action = 'open_trace'
GROUP BY d
ORDER BY d `

const GET_BUSINESS_USE_SQL = `SELECT
  to_char( ts, '%s' ) AS d,
  business_name,
  SUM ( cnt ) AS cnt 
FROM
  business_use_total
WHERE
    ts BETWEEN $1 AND $2
GROUP BY d,business_name`

const GET_GENERAL_RECORD_USE1_SQL = `SELECT
  to_char( ts, '%s' ) AS d,
  '%s' AS category,
  second_cat,
  '' AS third_cat,
  SUM ( cnt ) AS cnt 
FROM
  sp_general_records_total
WHERE
    ts BETWEEN $1 AND $2
	AND category='%s'
GROUP BY d, second_cat`

const GET_GENERAL_RECORD_USE2_SQL = `SELECT
  to_char( ts, '%s' ) AS d,
  '%s' AS category,
  '%s' AS second_cat,
  third_cat,
  SUM ( cnt ) AS cnt 
FROM
  sp_general_records_total
WHERE
    ts BETWEEN $1 AND $2
	AND category='%s'
	AND second_cat='%s'
GROUP BY d, third_cat`

const GET_GENERAL_RECORD_USE3_SQL = `SELECT
  to_char( ts, '%s' ) AS d,
  '%s' AS category,
  '%s' AS second_cat,
  '%s' AS third_cat,
  SUM ( cnt ) AS cnt 
FROM
  sp_general_records_total
WHERE
    ts BETWEEN $1 AND $2
	AND category='%s'
	AND second_cat='%s'
	AND third_cat='%s'
GROUP BY d`
